﻿namespace Leetcode.N0036.V1;
public class Solution
{
    public bool IsValidSudoku(char[][] board)
    {
        return this.IsValidRow(board) && this.IsValidCol(board) && this.IsValidBlock(board);
    }

    private bool IsValidRow(char[][] board)
    {
        for (int i = 0; i < 9; i++)
        {
            if (!this.IsValidRow(board, i))
            {
                return false;
            }
        }
        return true;
    }

    private bool IsValidRow(char[][] board, int row)
    {
        var hashset = new HashSet<int>();
        for (int i = 0; i < 9; i++)
        {
            if (board[row][i] != '.' && !hashset.Add(board[row][i]))
            {
                return false;
            }
        }
        return true;
    }

    private bool IsValidCol(char[][] board)
    {
        for (int i = 0; i < 9; i++)
        {
            if (!this.IsValidCol(board, i))
            {
                return false;
            }
        }
        return true;
    }

    private bool IsValidCol(char[][] board, int col)
    {
        var hashset = new HashSet<int>();
        for (int i = 0; i < 9; i++)
        {
            if (board[i][col] != '.' && !hashset.Add(board[i][col]))
            {
                return false;
            }
        }
        return true;
    }

    private bool IsValidBlock(char[][] board)
    {
        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                if (!this.IsValidBlock(board, i, j))
                {
                    return false;
                }
            }
        }
        return true;
    }

    private bool IsValidBlock(char[][] board, int blockRow, int blockCol)
    {
        var hashset = new HashSet<int>();
        for (int i = 0; i < 3; i++)
        {
            var row = blockRow * 3 + i;
            for (int j = 0; j < 3; j++)
            {
                var col = blockCol * 3 + j;
                if (board[row][col] != '.' && !hashset.Add(board[row][col]))
                {
                    return false;
                }
            }
        }
        return true;
    }
}